<?php
/**
 * @File name: skajax.inc.php
 * @author: 李枨煊
 * @Date: Tue Aug 05 13:45:40 CST 2008
 * @Copyright (C) , 2008, SUIKEE Co., Ltd.
 * @Desription: SKajax类
 */

class SkAjax
{
	public $url;	//SKAjax所在的URL路径
	public $debug;	//调试模式
	private $charset;	//字符编码
	private $function = array();	//注册的函数
	private $class = array();		//注册的类
	private $requestURI = '';			//Ajax访问路径
	
	//构造函数
	function __construct($url='./skajax/', $charset='utf-8', $debug=false)
	{
		$this->url = $url;
		$this->debug = $debug;
		$this->charset = $charset;
	}
	
	/**
	 * 注册函数
	 *
	 * @param 函数名 $func
	 */
	function registerFunction($func)
	{
		$this->function[] = $func;
	}
	
	/**
	 * 注册类与方法
	 *
	 * @param 类名 $class
	 * @param 方法名 $func
	 * @param [已实例化的对象] $object
	 */
	function registerClass($class, $func, $object=false)
	{
		if($object && !is_object($object))
		{
			if($this->debug)
			{
				echo "<br/><b>SkAjax Error: </b> This isn't a Object.<br/>";
				exit;
			}
		}
		else
		{
			$this->class[$class][$func] = $object;
		}
	}
	
	/**
	 * 设置ajax请求页面地址
	 *
	 * @param URL地址 $url
	 */
	function setRequestURI($url)
	{
		$this->requestURI = $url;
	}
	
	//取得JavaScript
	function getJavaScript()
	{
		$debug = (int)$this->debug;
		$result = "<script type='text/javascript' src='{$this->url}/js/skajax.js'></script><script type='text/javascript'>\n";
		$result .= "\$skAjax.requestURI = '{$this->requestURI}';\n";
		$result .= "\$skAjax.debug = {$debug};\n";
		
		foreach ($this->function as $key=>$value)	//处理注册的函数
		{
			$result .= "function skajax_{$value}() {\$skAjax.go('$value',arguments);}\n";
		}

		foreach ($this->class as $key1=>$value1)	//处理注册的类
		{
			$result .= "skajax_{$key1} = new Object();\n";
			foreach ($value1 as $key2=>$value2)
			{
				$result .= "skajax_{$key1}.{$key2} = function(){\$skAjax.goC('{$key1}', '{$key2}',arguments);}\n";
			}
		}
		$result .= '</script>';

		return $result;
	}
	
	//处理请求
	function processRequest()
	{
		isset($_POST['skajax']) ? $skajax = $_POST['skajax'] : $skajax = '';
		isset($_POST['class']) ? $class = $_POST['class'] : $class = '';	//所调用的类
		isset($_POST['func']) ? $func = $_POST['func'] : $func = '';	//所调用的类的方法
		isset($_POST['function']) ? $function = $_POST['function'] : $function = '';	//所调用的函数
		isset($_POST['param']) ? $param = $_POST['param'] : $param = '';	//函数的参数

		if(get_magic_quotes_gpc())	//如果有转义，去掉
		{
			$function = stripslashes($function);
			$class = stripslashes($class);
			$func = stripslashes($func);
			$param = json_decode(stripslashes($param));
		}
		
		if($this->charset !== 'utf-8' && $param)	//转码
		{
			$param = $this->convertCharset('utf-8', $this->charset, $param);
		}
		
		if(!$skajax)	//没有标识不操作
		{
			return false;
		}
		
		if((!$function && (!$class || !$func)) || !is_array($param))	//没有请求函数或类，或者参数非法
		{
			exit;
		}

		//之前不允许有输出
		if (headers_sent($filename, $linenumber))
		{
			echo "<br/><b>SkAjax Error: </b> Output has already been sent to the browser at {$filename}:{$linenumber}.<br/>";
			exit();
		}
		
		if($function)
		{
			if(!in_array($function,$this->function))	//非法提交函数，不操作
			{
				exit;
			}
			
			if (!function_exists($function))	//函数不存在
			{
				echo "<br/><b>SkAjax Error: </b> The function [<b>{$function}</b>] is not found.<br/>";
				exit;
			}
			$result = call_user_func_array($function,$param);
		}
		elseif($class)
		{
			if((!isset($this->class[$class]) || !isset($this->class[$class][$func])))	//非法提交对象
			{
				exit;
			}
			
			if(!$this->class[$class][$func] && !class_exists($class))	//类不存在
			{
				echo "<br/><b>SkAjax Error: </b> The class [<b>{$class}</b>] is not found.<br/>";
				exit;
			}
			
			if(!method_exists($class, $func))	//类的方法不存在
			{
				echo "<br/><b>SkAjax Error: </b> The class {$class}'s function [<b>{$func}</b>] is not found.<br/>";
				exit;
			}
			
			if($this->class[$class][$func])	//动态调用
			{
				$result = call_user_func_array(array($this->class[$class][$func], $func),$param);
			}
			else	//静态调用
			{
				$result = call_user_func_array(array($class, $func),$param);
			}
		}

		echo $result->getJson($this->charset);		
		exit;
	}
	
	/**
	 * 转换编码
	 *
	 * @param 旧编码 $oldCharset
	 * @param 新编码 $newCharset
	 * @param 对象、字符串 $object
	 * @return 结果
	 */
	function convertCharset($oldCharset, $newCharset, $object)
	{
		$type = gettype($object);	//取得字符类型
		
		switch ($type)
		{
			case 'object' :	//对象
				foreach ($object as $key=>$value)
				{
					$key = $this->convertCharset($oldCharset, $newCharset, $key);
					$result->$key = $this->convertCharset($oldCharset, $newCharset, $value);
				}
				return $result;
			case 'array' :	//数组
				foreach ($object as $key=>$value)
				{
					$key = $this->convertCharset($oldCharset, $newCharset, $key);
					$result[$key] = $this->convertCharset($oldCharset, $newCharset, $value);
				}
				return $result;
			case 'string' :	//字符串
				return iconv($oldCharset, $newCharset, $object);
			default :		//数字等其它
				return $object;
		}
	}
	
}

//skAjax回应类
class SkAjaxResponse
{
	private $results = array();
	
	/**
	 * 弹出提示窗口
	 *
	 * @param 提示内容 $str
	 */
	function alert($str)
	{
		$this->results[] = array(
			'ac'	=> 'al',
			'val'	=> $str);
	}
	
	/**
	 * 替换属性值
	 *
	 * @param DOM标签ID $id
	 * @param 属性 $property
	 * @param 值 $val
	 */
	function assign($id, $property, $val)
	{
		$this->results[] = array(
			'ac'		=> 'as',
			'id'		=> $id,
			'property'	=> $property,
			'val'		=> $val,
		);
	}
	
	/**
	 * 跳转
	 *
	 * @param 网址 $url
	 */
	function goto($url)
	{
		$this->results[] = array(
			'ac'	=> 'gt',
			'val'	=> $url,);
	}
	
	/**
	 * 前进后台多少项
	 *
	 * @param +1/-1 $num
	 */
	function history($num)
	{
		$this->results[] = array(
			'ac'	=> 'ht',
			'val'	=> $num,
		);
	}
	
	/**
	 * 提示操作
	 *
	 * @param 显示的文本 $text
	 * @param 跳转URL $url
	 * @param 多少时间消失(秒) $timeout
	 * @param 边框颜色 $borderColor
	 * @param 边框宽度 $borderWidth
	 * @param 文字颜色 $innerColor
	 * @param 文字背景 $innerBgColor
	 * @param 宽 $width
	 * @param 内间距 $padding
	 */
	function hint($text, $url=null, $timeout=2, $borderColor=null, $borderWidth=null, $innerColor=null, $innerBgColor=null, $width=null, $padding=null)
	{
		$this->results[] = array(
			'ac'	=> 'hi',
			'tx'	=> $text,
			'tm'	=> (int)$timeout,
			'ur'	=> $url,
			'bc'	=> $borderColor,
			'bw'	=> $borderWidth,
			'ic'	=> $innerColor,
			'ib'	=> $innerBgColor,
			'wi'	=> $width,
			'pd'	=> $padding,
		);
	}
	
	//刷新页面
	function reload()
	{
		$this->results[]['ac'] = 're';
	}
	
	//关闭页面
	function close()
	{
		$this->results[]['ac'] = 'cl';
	}
	
	/**
	 * 执行JavaScript代码
	 *
	 * @param JS代码 $js
	 */
	function script($js)
	{
		$this->results[] = array(
			'ac'	=> 'js',
			'val'	=> $js);
	}
	
	/**
	 * 取得JSON
	 *
	 * @param 编码 $charset
	 * @return JSON数据
	 */
	function getJson($charset='utf-8')
	{
		if($charset !== 'utf-8')	//非UTF-8编码，转码
		{
			foreach ($this->results as $key1=>$value1)
			{
				foreach ($value1 as $key2=>$value2)
				{
					$result[$key1][$key2] = iconv($charset, 'utf-8', $value2);
				}
			}
		}
		else
		{
			$result = & $this->results;
		}
		
		return json_encode($result);
	}
}

global $cfg_domain, $skAjax;
$skAjax = new SkAjax('/libs/skajax', 'utf-8', false);